using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.IO;
using UnityEngine;

namespace Galplay {
  public class GameScene {
    public GameProject Owner { get; }
    public string Name { get; }
    public string Filename { get; }
    public string FullPath { get => Owner.GetPath(Path.Combine("Scenes", Filename)); }
    public string Icon { get; }
    public string Content => Owner.GetMaster(Path.Combine("Scenes", Filename));

    public GameScene(GameProject owner, XmlNode xml) {
      Owner = owner;
      Name = xml.GetStr("Name");
      Filename = xml.InnerText;
      Icon = xml.GetStr("Icon");
    }
  }

  public class GameProject {
    public string Name { get; }
    public string FullPath { get; }
    public bool IsFolder { get; }
    public bool IsZip { get; }

    public static readonly string GAME_MASTER_PATH = "Game.xml";
    public static readonly string GAME_PACK_PATH = "Game.mov";
    public static readonly string GAME_ASSET_PATH = "Assets.mov";
    public static readonly string GAME_ASSET_INDEX = "Assets.xml";

    public List<GameScene> Scenes { get; set; }
    public string EventPath { get; set; }
    public string VoicePath { get; private set; }
    public string ImagePath { get; private set; }
    public string BgmPath { get; private set; }
    public string BgsPath { get; internal set; }
    public bool UseCharaTitle { get; set; } = false;

    public string FullEventsPath => GetPath(EventPath);
    private ZipManager GameMaster { get; set; }
    private PackAssets GameAssets { get; set; }

    public int Width { get; private set; }
    public int Height { get; private set; }
    public string TitleIconFullPath => GetPath("Title.png");
    public bool IsLoaded { get; private set; } = false;

    public GameProject(string path) {
      Scenes = new List<GameScene>();

      // 验证路径非空
      if (string.IsNullOrWhiteSpace(path))
        throw new ArgumentException("Path cannot be null or empty", nameof(path));

      // 标准化路径（处理相对路径、统一分隔符等）
      FullPath = Path.GetFullPath(path);

      // 提取名称（如果是目录取目录名，文件取不带扩展名的文件名）
      Name = Path.GetFileName(FullPath.TrimEnd(Path.DirectorySeparatorChar));
    }

    private async Task<ZipManager> LoadZipManager(string path) {
      return await Task.Run(() => {
        // 这里实现实际的XML加载逻辑
        return new ZipManager(File.ReadAllBytes(GetPath(path)));
      });
    }

    private async Task<PackAssets> LoadZipAssets(string path) {
      return await Task.Run(() => {
        // 这里实现实际的XML加载逻辑
        return new PackAssets(GetPath(GAME_ASSET_PATH),
          new XmlReader(GameMaster.GetString(GAME_ASSET_INDEX)));
      });
    }

    public string GetMaster(string path) {
      var str = GameMaster.GetString(path);
      return str;
    }

    public async void Load(Action callback) {
      if (IsLoaded) {
        Debuger.LogError("Pass for IsLoaded.");
        callback?.Invoke();
        return;
      }

      GameMaster = await LoadZipManager(GAME_PACK_PATH);
      GameMaster.ReadAllFiles();
      GameAssets = await LoadZipAssets(GAME_ASSET_PATH);

      var xml = new XmlReader(GetMaster(GAME_MASTER_PATH));

      var cfg = xml.Root;
      Width = cfg.GetInt("Width");
      Height = cfg.GetInt("Height");

      AddSound("BGM", cfg.GetStr("BGM"));
      AddSound("BGS", cfg.GetStr("BGS"));
      AddSound("SE", cfg.GetStr("SE"));

      EventPath = cfg.GetStr("Events");
      VoicePath = cfg.GetStr("VoicePath");
      ImagePath = cfg.GetStr("ImagePath");
      BgmPath = cfg.GetStr("BgmPath");
      BgsPath = cfg.GetStr("BgsPath");
      UseCharaTitle = cfg.GetBool("UseCharaTitle");

      var scenes = cfg.GetNodes("Scene");
      foreach (var scen in scenes) {
        Scenes.Add(new GameScene(this, scen));
      }

      IsLoaded = true;

      // 3. 所有操作完成后执行回调
      callback?.Invoke();
    }

    private void AddSound(string name, string path) {
      // 如果没有设置，那么跳过（Wolf需要这个，吉里吉里直接指定）
      if (path == null) { return; }
      SoundManager.Instance.Add(name, new XmlReader(GetMaster(path)));
    }

    public string GetPath(string path) {
      // 如果Path为null，那么直接返回null
      if (path == null || path.Length == 0) { return null; }

      var ext = Path.GetExtension(path);
      if (ext.Equals(".xml", StringComparison.OrdinalIgnoreCase)) {
        path = Path.ChangeExtension(path, ".gif");
      }

      // 确保路径使用正确的分隔符
      string normalizedPath = path.Replace('\\', '/');

      // 组合完整路径
      string fullPath = Path.Combine(FullPath, normalizedPath);


      return fullPath;

    }

    public string GetAsset(string path) {
      if (Kit.IsEmpty(path)) { return null; }
      return GetPath(Path.Combine("Assets", path));
    }

    public PackAssetItem GetAssetFile(string relativePath){
      return GameAssets.Get(relativePath);
    }

  }
}